
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'


/**
 *  判断是不是PromiseLike
 * @param {*} obj 
 * @returns boolean isPromiseLike
 */
const isPromiseLike = (obj) => {
  // return  obj instanceof MyPromise
  return obj.then && typeof obj.then === 'function'
}


/**
 * 模拟微任务
 * @param {*} func 
 */
const runMicroTask = (func) => {
  if (typeof queueMicrotask === 'function') {
    queueMicrotask(func)
  } else if (typeof process === 'object' && typeof process.nextTick === 'function') {
    process.nextTick(func)
  } else if (typeof MutationObserver === 'function') {
    const text = document.createTextNode('')
    const observer = new MutationObserver(func)
    observer.observe(text, { characterData: true })
    text.data = '1'
  } else {
    setTimeout(func)
  }
}



// leader 


/**
 * MyPromise 手写 Promise 源码
 */
class MyPromise {
  #result = void 0;
  #state = PENDING;
  #handlers = []

  constructor(executor) {
    const outResolve = (data) => {
      this.#changeState(FULFILLED, data)
    }
    const outReject = (data) => {
      this.#changeState(REJECTED, data)
    }
    try {
      executor(outResolve, outReject)
    } catch (error) {
      reject(error)
    }
  }

  #runOne(callback, resolve, reject) {
    runMicroTask(() => {
      if (typeof callback !== 'function') {
        const settled = this.#state === FULFILLED ? resolve : reject
        settled(this.#result)
        return
      }
      try {
        const data = callback(this.#result)
        if (isPromiseLike(data)) {
          data.then(resolve, reject)
          return
        } else {
          resolve(data)
        }
      } catch (error) {
        reject(error)
      }
    })
  }
  #run() {
    // then回调进入微队列的时机
    // 1. 调用then的时候, 如果已经完成状态,直接进入微队列
    if (this.#state === PENDING) return
    // 2. resolve完成状态, 所有注册的then回调进入微队列
    while (this.#handlers.length) {
      const { onFulfilled, onRejected, resolve, reject } = this.#handlers.shift()
      if (this.#state === FULFILLED) {
        this.#runOne(onFulfilled, resolve, reject)
      } else if (this.#state === REJECTED) {
        this.#runOne(onRejected, resolve, reject)
      }
    }
  }
  #changeState(state, result) {
    if (this.#state !== PENDING) return
    this.#state = state
    this.#result = result
    this.#run()
  }

  // then方法返回一个新的Promise
  then(onFulfilled, onRejected) {
    const myP = new MyPromise((resolve, reject) => {
      this.#handlers.push({ onFulfilled, onRejected, resolve, reject })
      this.#run()
    })
    return myP
  }


  catch(onRejected) {
    return this.then(null, onRejected)
  }
  finally(callback) {
    return this.then(
      value => {
        callback()
        return value
      },
      reason => {
        callback()
        throw reason
      },
    )
  }
  static resolve(value) {
    if (value instanceof Promise) return value;
    return new MyPromise((resolve, reject) => {
      if (
        isPromiseLike(value)
      ) {
        value.then(resolve, reject)
      } else {
        resolve(value)
      }
    })
  }
  static reject(value) {
    return new MyPromise((_, reject) => {
      reject(value)
    })
  }
  static try(callback) {
    return new MyPromise((resolve,) => {
      resolve(callback())
    })
  }
  static race() {
    return new MyPromise((resolve, reject) => {
      promiseArray.forEach(item => {
        item.then(resolve, reject)
      })
    })
  }
  static any() {
    return new MyPromise((resolve, reject) => {
      let arrayLength = array.length;
      let errList = [];
      if (array && typeof array[Symbol.iterator] === "function") {
        array.forEach((value, index) => {
          Promise.resolve(value).then(
            (res) => {
              resolve(res);
            },
            (err) => {
              errList[index] = new Error(err);
              if (errList.length === arrayLength) {
                reject(new AggregateError(errList));
              }
            },
          );
        });
      }
    })
  }

  static all(promiseArray) {
    return new MyPromise((resolve, reject) => {
      let result = []
      let count = 0
      for (let i = 0; i < promiseArray.length; i++) {
        promiseArray[i].then(res => {
          result[i] = res
          count++
          if (count === promiseArray.length) {
            resolve(result)
          }
        }, reject)
      }
    })
  }
  //实现 Promise.allSettled
  static allSettled(promiseArray) {
    return new MyPromise((resolve,) => {
      const results = [];
      // 处理每个 Promise
      promiseArray.forEach((itemPromise, index) => {
        itemPromise.resolve(promise)
          .then(value => {
            results[index] = {
              status: FULFILLED,
              value
            };
          })
          .catch(reason => {
            results[index] = {
              status: REJECTED,
              reason
            };
          })
          .finally(() => {
            // 检查是否所有 Promise 都已处理完毕
            if (results.length === promiseArray.length) {
              resolve(results);
            }
          });
      });
    });


  }
}

//#region 
window.addEventListener('unhandledrejection', () => {
  console.log('== unhandledrejection ===>',)
})
window.addEventListener('rejectionhandled', () => {
  console.log('== rejectionhandled ===>',)
})
//#endregion

// FID
// FCP
// LCP
// TBT
// TTI
// CSL

